package io.kiki.sba.registry.server.metadata.remoting.meta;

import io.kiki.sba.registry.api.ChannelHandler;
import io.kiki.sba.registry.api.exchange.DataExchanger;
import io.kiki.sba.registry.common.model.elector.Leader;
import io.kiki.sba.registry.exception.MetaLeaderQueryException;
import io.kiki.sba.registry.server.metadata.MetadataLeaderService;
import io.kiki.sba.registry.server.metadata.bootstrap.config.ServerConfig;
import io.kiki.sba.registry.server.shared.constant.CentralControlLeaderLearnModeEnum;
import io.kiki.sba.registry.server.shared.meta.AbstractCentralControlLeaderExchanger;
import io.kiki.sba.registry.util.StringFormatter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collection;
import java.util.Collections;

@Slf4j
public class LocalCentralControlExchanger extends AbstractCentralControlLeaderExchanger {

    @Autowired
    private ServerConfig serverConfig;
    @Autowired
    private MetadataLeaderService metadataLeaderService;

    public LocalCentralControlExchanger() {

        super(DataExchanger.META_SERVER_TYPE);
    }

    @Override
    protected CentralControlLeaderLearnModeEnum getMode() {
        if (defaultCommonConfig.isJdbc()) {
            return CentralControlLeaderLearnModeEnum.jdbc;
        } else {
            return CentralControlLeaderLearnModeEnum.loadbalancer;
        }
    }

    @Override
    public Leader queryLeaderFromDb() {
        try {
            return retryer.call(() -> {
                long leaderEpoch = metadataLeaderService.getLeaderEpoch();
                String leader = metadataLeaderService.getLeader();
                io.kiki.sba.registry.store.api.elector.Leader hasNoLeader = io.kiki.sba.registry.store.api.elector.Leader.HAS_NO_LEADER;
                if (leaderEpoch == hasNoLeader.getEpoch() || StringUtils.equals(leader, hasNoLeader.getLeader())) {
                    return null;
                }
                return new Leader(leader, leaderEpoch);
            });
        } catch (Throwable e) {
            throw new MetaLeaderQueryException(StringFormatter.format("query meta leader error from db failed"), e);
        }
    }

    @Override
    protected Collection<String> getCentralControlServerDomains(String dataCenter) {
        return Collections.emptyList();
    }

    @Override
    public int getRpcTimeoutMillis() {
        return serverConfig.getMetaNodeExchangeTimeoutMillis();
    }

    @Override
    public int getServerPort() {
        return serverConfig.getMetaServerPort();
    }

    @Override
    public int getConnNum() {
        return 3;
    }

    @Override
    protected Collection<ChannelHandler> getClientHandlers() {
        return Collections.emptyList();
    }
}
